'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

var _toQueryString = require('../utils/toQueryString');

var _toQueryString2 = _interopRequireDefault(_toQueryString);

var _processHeader = require('./processHeader');

var _processHeader2 = _interopRequireDefault(_processHeader);

var _customResponse = require('./customResponse');

var _customResponse2 = _interopRequireDefault(_customResponse);

var _customError = require('../customError');

var _error = require('../actions/error');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

// avoid warning when developer dosn't handle api customError.
window.addEventListener('unhandledrejection', function (e) {
  e.preventDefault();
});

/**
 * 用于创建fetch请求
 * @class Request
 * @memberOf fe-lib.FetchRequest
 * @inner
 */

var CustomRequest = function () {

  /**
   * @constructor
   */
  function CustomRequest() {
    var _this = this;

    _classCallCheck(this, CustomRequest);

    ['get', 'post', 'put', 'patch', 'delete', 'head'].forEach(function (method) {
      _this[method] = function (path) {
        var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
            _ref$ajaxCache = _ref.ajaxCache,
            ajaxCache = _ref$ajaxCache === undefined ? true : _ref$ajaxCache,
            _ref$headers = _ref.headers,
            headers = _ref$headers === undefined ? {} : _ref$headers,
            _ref$credentials = _ref.credentials,
            credentials = _ref$credentials === undefined ? 'include' : _ref$credentials,
            _ref$mode = _ref.mode,
            mode = _ref$mode === undefined ? 'cors' : _ref$mode,
            _ref$body = _ref.body,
            body = _ref$body === undefined ? undefined : _ref$body;

        var url = path;
        var fetchConfig = {
          method: method,
          headers: (0, _processHeader2.default)(headers),
          credentials: credentials,
          mode: mode
        };

        var params = body;
        if (fetchConfig.headers['Content-Type'] !== 'application/json') {
          params = (0, _toQueryString2.default)(body);
        }

        if (method !== 'get' && method !== 'delete') {
          fetchConfig.body = params;
        } else {
          var paramList = [];
          if (params) {
            paramList.push(params);
          }
          if (ajaxCache) {
            paramList.push('_timestamp=' + Date.now());
          }
          if (paramList.length > 0) {
            url = url + '?' + paramList.join('&');
          }
        }

        return fetch(url, fetchConfig).then(function () {
          var res = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};

          var ret = CustomRequest.preHandleResponse(res);
          if (ret) {
            throw ret;
          }

          var status = res.status,
              _res$statusText = res.statusText,
              statusText = _res$statusText === undefined ? '' : _res$statusText,
              ok = res.ok;

          if (ok) {
            return res.json();
          }

          throw new _customError.CustomError(statusText, _customError.CustomErrorType.HTTP, {
            code: status,
            url: url
          });
        }).then(function (json) {
          var response = new _customResponse2.default(json);
          if (response.success) {
            return _extends({}, response);
          }

          throw new _customError.CustomError(response.message, _customError.CustomErrorType.SERVICE, {
            code: response.code,
            url: url
          });
        }).catch(function (error) {
          if (CustomRequest.dispatch) {
            CustomRequest.dispatch((0, _error.reportError)(error));
          } else {
            console.warn(JSON.stringify(error));
          }
          throw error;
        });
      };
    });
  }

  /**
   * 绑定store到Request
   * @function connectToRedux
   * @param store - redux store
   * @memberOf Request
   * @static
   */


  CustomRequest.connectToRedux = function connectToRedux(store) {
    CustomRequest.dispatch = store.dispatch;
  };

  /**
   * 预处理fetch请求响应头
   */


  CustomRequest.preHandleResponse = function preHandleResponse() {
    return false;
  };

  CustomRequest.resetStatic = function resetStatic(methods) {
    Object.keys(methods).forEach(function (key) {
      return CustomRequest[key] = methods[key];
    });
  };

  return CustomRequest;
}();

CustomRequest.instance = new CustomRequest();
CustomRequest.dispatch = null;
exports.default = CustomRequest;